/*  */
#include <string.h>
#include "cstdlib.h"
#include "../interpreter.h"
#include "../table.h"

static int String_ZeroValue = 0;

void Cstdlib::StringStrcpy(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strcpy((char *)param[0]->val->pointer,
                                       (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrncpy(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strncpy((char *)param[0]->val->pointer,
                                        (char *)param[1]->val->pointer, param[2]->val->integer);
}

void Cstdlib::StringStrcmp(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strcmp((char *)param[0]->val->pointer,
                                       (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrncmp(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strncmp((char *)param[0]->val->pointer,
                                        (char *)param[1]->val->pointer, param[2]->val->integer);
}

void Cstdlib::StringStrcat(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strcat((char *)param[0]->val->pointer,
                                       (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrncat(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strncat((char *)param[0]->val->pointer,
                                        (char *)param[1]->val->pointer, param[2]->val->integer);
}

#ifndef WIN32
void Cstdlib::StringIndex(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = index(param[0]->val->pointer,
        param[1]->val->integer);
}

void Cstdlib::StringRindex(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = rindex(param[0]->val->pointer,
        param[1]->val->integer);
}
#endif

void Cstdlib::StringStrlen(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strlen((char *)param[0]->val->pointer);
}

void Cstdlib::StringMemset(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = memset(param[0]->val->pointer,
        param[1]->val->integer, param[2]->val->integer);
}

void Cstdlib::StringMemcpy(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = memcpy(param[0]->val->pointer,
        param[1]->val->pointer, param[2]->val->integer);
}

void Cstdlib::StringMemcmp(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = memcmp(param[0]->val->pointer,
        param[1]->val->pointer, param[2]->val->integer);
}

void Cstdlib::StringMemmove(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = memmove(param[0]->val->pointer,
        param[1]->val->pointer, param[2]->val->integer);
}

void Cstdlib::StringMemchr(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = memchr(param[0]->val->pointer,
        param[1]->val->integer, param[2]->val->integer);
}

void Cstdlib::StringStrchr(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strchr((char *)param[0]->val->pointer,
        param[1]->val->integer);
}

void Cstdlib::StringStrrchr(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strrchr((char *)param[0]->val->pointer,
        param[1]->val->integer);
}

void Cstdlib::StringStrcoll(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strcoll((char *)param[0]->val->pointer,
                                        (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrerror(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strerror(param[0]->val->integer);
}

void Cstdlib::StringStrspn(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strspn((char *)param[0]->val->pointer,
                                       (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrcspn(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strcspn((char *)param[0]->val->pointer,
                                        (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrpbrk(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strpbrk((char *)param[0]->val->pointer,
        (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrstr(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strstr((char *)param[0]->val->pointer,
                                       (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrtok(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = strtok((char *)param[0]->val->pointer,
                                       (char *)param[1]->val->pointer);
}

void Cstdlib::StringStrxfrm(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strxfrm((char *)param[0]->val->pointer,
                                        (char *)param[1]->val->pointer, param[2]->val->integer);
}

#ifndef WIN32
void Cstdlib::StringStrdup(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = (void*)strdup(param[0]->val->pointer);
}

void Cstdlib::StringStrtok_r(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = (void*)strtok_r(param[0]->val->pointer,
        param[1]->val->pointer, param[2]->val->pointer);
}
#endif

/* all string.h functions */
const LibraryFunction Cstdlib::StringFunctions[] =
{
#ifndef WIN32
	{Cstdlib::StringIndex,   "char *index(char *,int);"},
    {Cstdlib::StringRindex,  "char *rindex(char *,int);"},
#endif
    {Cstdlib::StringMemcpy,  "void *memcpy(void *,void *,int);"},
    {Cstdlib::StringMemmove, "void *memmove(void *,void *,int);"},
    {Cstdlib::StringMemchr,  "void *memchr(char *,int,int);"},
    {Cstdlib::StringMemcmp,  "int memcmp(void *,void *,int);"},
    {Cstdlib::StringMemset,  "void *memset(void *,int,int);"},
    {Cstdlib::StringStrcat,  "char *strcat(char *,char *);"},
    {Cstdlib::StringStrncat, "char *strncat(char *,char *,int);"},
    {Cstdlib::StringStrchr,  "char *strchr(char *,int);"},
    {Cstdlib::StringStrrchr, "char *strrchr(char *,int);"},
    {Cstdlib::StringStrcmp,  "int strcmp(char *,char *);"},
    {Cstdlib::StringStrncmp, "int strncmp(char *,char *,int);"},
    {Cstdlib::StringStrcoll, "int strcoll(char *,char *);"},
    {Cstdlib::StringStrcpy,  "char *strcpy(char *,char *);"},
    {Cstdlib::StringStrncpy, "char *strncpy(char *,char *,int);"},
    {Cstdlib::StringStrerror,"char *strerror(int);"},
    {Cstdlib::StringStrlen,  "int strlen(char *);"},
    {Cstdlib::StringStrspn,  "int strspn(char *,char *);"},
    {Cstdlib::StringStrcspn, "int strcspn(char *,char *);"},
    {Cstdlib::StringStrpbrk, "char *strpbrk(char *,char *);"},
    {Cstdlib::StringStrstr,  "char *strstr(char *,char *);"},
    {Cstdlib::StringStrtok,  "char *strtok(char *,char *);"},
    {Cstdlib::StringStrxfrm, "int strxfrm(char *,char *,int);"},
#ifndef WIN32
	{Cstdlib::StringStrdup,  "char *strdup(char *);"},
    {Cstdlib::StringStrtok_r,"char *strtok_r(char *,char *,char **);"},
#endif
    {NULL,          NULL }
};

/* creates various system-dependent definitions */
void Cstdlib::StringSetupFunc(Interpreter *pc)
{
    /* define NULL */
    if (!(pc, MyTable::TableStrRegister(pc, "NULL")))
        (pc, NULL, "NULL", &pc->intType,
            (union AnyValue*)&String_ZeroValue, false);
}

